package com.bryandismas.pcsx.emulator;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.util.AttributeSet;

public class EmulatorView extends GLSurfaceView implements GLSurfaceView.EGLContextFactory, GLSurfaceView.Renderer
{
	public EmulatorView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		init();
	}
	
	public EmulatorView(Context context)
	{
		super(context);
		init();
	}

	void init()
	{
		// set up gles 2..
		//setEGLContextFactory(this);
		
		setRenderer(this);
	}

	// context factory functions..
	@Override
	public EGLContext createContext(EGL10 egl, EGLDisplay display,
			EGLConfig eglConfig)
	{
		int[] attr = { 0x3098, 2, EGL10.EGL_NONE };
		EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attr);
		return context;
	}
	
	@Override
	public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context)
	{
		egl.eglDestroyContext(display, context);
	}
	
	@Override
	public void onDrawFrame(GL10 gl)
	{
		gl.glClearColor(0,0,0, 1);
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
		
		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();

		float[] verts = {
				-1, -1, 0,
				1, -1, 0,
				1, 1, 0,
				1, 1, 0,
				-1, 1, 0,
				-1, -1, 0
		};
		GLU.gluLookAt(gl, 0, 0, 10, 0, 0, 0, 0, 1, 0);
		ByteBuffer vbb = ByteBuffer.allocateDirect(verts.length * 4);
		vbb.order(ByteOrder.nativeOrder());
		FloatBuffer vertexBuffer = vbb.asFloatBuffer();
		vertexBuffer.put(verts);
		vertexBuffer.position(0);

		gl.glDisable(GL10.GL_LIGHTING);
		gl.glDisable(GL10.GL_CULL_FACE);
		
		gl.glPushMatrix();
		gl.glRotatef(angle, 0, 1, 0);
		gl.glTranslatef(0, 0, 2);
		gl.glColor4f(1, 0, 0, 1);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glPopMatrix();
		
		gl.glPushMatrix();
		gl.glRotatef(angle, 0, 1, 0);
		gl.glTranslatef(0, 0, -2);
		gl.glColor4f(0, 0, 1, 1);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
		gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glPopMatrix();
		
		angle += 1;
	}
	
	float angle = 0;
	
	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height)
	{
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glViewport(0, 0, width, height);
		GLU.gluPerspective(gl, 50, (float)width/(float)height, 0.1f, 10000);
	}
	
	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config)
	{
		// Enable Smooth Shading, default not really needed.
		gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs.
		// Depth buffer setup.
		gl.glClearDepthf(1.0f);// OpenGL docs.
		// Enables depth testing.
		gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs.
		// The type of depth testing to do.
		gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs.
		// Really nice perspective calculations.
		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.
                          GL10.GL_NICEST);
	}
}
